package com.eight.cloud.payment.core.wechat.mode;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.eight.cloud.client.model.dto.PlatformOrderDto;
import com.eight.cloud.client.model.vo.OrderVo;
import com.eight.cloud.payment.common.enums.PayStrategyEnum;
import com.eight.cloud.payment.config.WechatServiceProviderConfig;
import com.eight.cloud.payment.core.wechat.channel.WxPay;
import com.eight.cloud.payment.entity.SubPayOrderEntity;
import com.eight.cloud.payment.model.vo.MerchantAppVo;
import com.eight.cloud.payment.model.vo.SubPayOrderVo;
import com.eight.cloud.payment.service.IMerchantAppService;
import com.eight.cloud.payment.service.ISubPayOrderService;
import com.eight.cloud.redisson.utils.RedisUtils;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.partnerpayments.nativepay.NativePayService;
import com.wechat.pay.java.service.partnerpayments.nativepay.model.*;
import org.springframework.stereotype.Service;

/**
 * @ClassName: WxPay
 * @Description: 微信原生支付（扫码支付）
 * @Author: TXC
 * @Date: 2024-12-25 09:29
 **/
@Service
public class WxNativePay extends WxPay {
    private final WechatServiceProviderConfig wechatServiceProviderConfig;
    private final NativePayService nativePayService;
    private final ISubPayOrderService subPayOrderService;

    public WxNativePay(RSAAutoCertificateConfig rsaAutoCertificateConfig,
                       WechatServiceProviderConfig wechatServiceProviderConfig, RedisUtils redisUtils,
                       ISubPayOrderService subPayOrderService, IMerchantAppService merchantAppService) {
        super(rsaAutoCertificateConfig, wechatServiceProviderConfig, redisUtils, merchantAppService);
        this.wechatServiceProviderConfig = wechatServiceProviderConfig;
        this.nativePayService = new NativePayService.Builder().config(rsaAutoCertificateConfig).build();
        this.subPayOrderService = subPayOrderService;
    }

    @Override
    public String pay(PlatformOrderDto order) {
        MerchantAppVo merchantApp = getAccount(order.getSubMerchantId());
        // 构建service
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(Integer.valueOf(order.getPriceFen()));
        request.setAmount(amount);
        request.setSpMchid(wechatServiceProviderConfig.getMerchantId());
        request.setSpAppid(wechatServiceProviderConfig.getAppid());
        request.setDescription(order.getTitle());
        request.setOutTradeNo(order.getUuid());
        request.setNotifyUrl(wechatServiceProviderConfig.getNotifyServiceUrl() + PAR_NOTIFY_URL);
        request.setSubAppid(merchantApp.getSubAppid());
        request.setSubMchid(order.getSubMerchantId());
        // 调用下单方法，得到应答
        try {
            PrepayResponse response = nativePayService.prepay(request);
            if (StrUtil.isNotEmpty(order.getNotifyUrl())) {
                cacheClientNotifyUrl(order.getUuid(), order.getNotifyUrl());
            }
            return response.getCodeUrl();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }


    @Override
    public OrderVo queryOrderById(SubPayOrderVo subPayOrder) {
        QueryOrderByIdRequest request = new QueryOrderByIdRequest();
        request.setTransactionId(subPayOrder.getTransactionId());
        request.setSubMchid(subPayOrder.getMerchantId());
        request.setSpMchid(wechatServiceProviderConfig.getMerchantId());
        Transaction transaction = nativePayService.queryOrderById(request);
        OrderVo orderVo = new OrderVo();
        BeanUtil.copyProperties(transaction, orderVo);
        if (transaction != null && transaction.getPayer() != null) {
            orderVo.setSubOpenid(transaction.getPayer().getSubOpenid());
        } else {
            orderVo.setSubOpenid(null);
        }
        return orderVo;
    }

    @Override
    public OrderVo queryOrderByOutTradeNo(SubPayOrderVo subPayOrder) {
        QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
        request.setOutTradeNo(subPayOrder.getUuid());
        request.setSubMchid(subPayOrder.getMerchantId());
        request.setSpMchid(wechatServiceProviderConfig.getMerchantId());
        Transaction transaction = nativePayService.queryOrderByOutTradeNo(request);
        OrderVo orderVo = new OrderVo();
        BeanUtil.copyProperties(transaction, orderVo);
        if (transaction != null && transaction.getPayer() != null) {
            orderVo.setSubOpenid(transaction.getPayer().getSubOpenid());
        } else {
            orderVo.setSubOpenid(null);
        }
        orderVo.setOutTradeNo(subPayOrder.getSubOrderId());
        return orderVo;
    }

    @Override
    public String closeOrder(SubPayOrderVo subPayOrder) {
        CloseOrderRequest request = new CloseOrderRequest();
        request.setSubMchid(subPayOrder.getMerchantId());
        request.setSpMchid(wechatServiceProviderConfig.getMerchantId());
        request.setOutTradeNo(subPayOrder.getUuid());
        nativePayService.closeOrder(request);
        subPayOrderService.updateSubPayOrder(subPayOrder.getUuid(), null, SubPayOrderEntity.PayStatusEnum.CLOSE.getValue());
        return null;
    }

    @Override
    public PayStrategyEnum getPayStrategy() {
        return PayStrategyEnum.WX_NATIVE;
    }

}
